﻿using System.Collections.Generic;
using System.Diagnostics;
using System.Web.Mvc;
using BLL.Services;
using BLL.Services.Authors;
using BLL.Services.Authors.Listing;
using MvcContrib.Sorting;
using MvcContrib.UI.Grid;
using Web.Areas.Admin.Infrastructure;
using Web.Areas.Admin.Models.Authors;
using Web.Infrastructure;
using Web.Infrastructure.Models;
using Web.Infrastructure.Security;

namespace Web.Areas.Admin.Controllers
{
    /// <summary>
    /// The authors controller.
    /// </summary>
    [AdminAuthorization]
    public partial class AuthorsController : AdminController
    {
        private readonly IAuthorsService _authorsService;

        public AuthorsController(IAuthorsService usersService)
        {
            _authorsService = usersService;
        }

        public virtual ActionResult Index()
        {
            return BackBoneView(MVC.Admin.Shared.Views.Empty);
        }

        public virtual ActionResult ListingTemplate()
        {
            return BackBoneView(MVC.Admin.Authors.Views.Listing);
        }

        [ListingAction("LastName")]
        public virtual ActionResult Listing(GridSortOptions sort, int size, int page, AuthorFilter filter)
        {
            var model = _authorsService.GetListingAuthor(
                page, size, sort.Column, sort.Direction != SortDirection.Descending ? 0 : 1, filter);
            return BackBoneJson(model);
        }

        /// <summary>
        /// Deletes selected items.
        /// </summary>
        /// <param name="items">Items to delete.</param>
        public virtual ActionResult Delete(int[] items)
        {
            var model = new BaseModel();
            foreach (var item in items)
            {
                try
                {
                    _authorsService.Delete(item);
                }
                catch (ServiceException exception)
                {
                    ModelState.AddModelError(string.Empty, exception.ToString());
                    Trace.TraceError(exception.ToString());
                }
            }
            model.Errors = GetErrors;
            if (ModelState.IsValid)
            {
                model.SuccessMessage = "Author have been successfully deleted.";
            }
            return Json(model);
        }

        [HttpGet]
        public virtual ActionResult Create()
        {
            return BackBoneView(MVC.Admin.Shared.Views.Empty);
        }

        /// <summary>
        /// Show form for create Author
        /// </summary>
        [HttpGet]
        public virtual ActionResult CreateTemplate()
        {
            return BackBoneView(MVC.Admin.Authors.Views.Create, new AuthorCreateModel());
        }

        /// <summary>
        /// Creates the specified model.
        /// </summary>
        /// <param name="model">The model.</param>
        [HttpPost]
        public virtual ActionResult Create(AuthorCreateModel model)
        {
            if (!ModelState.IsValid)
            {
                model.Errors = GetErrors;
                return Json(model);
            }
            var author = (Author)model;
            try
            {
                _authorsService.Create(author);
                model.SuccessMessage = "Author has been successfully created.";
                return Json(model);
            }
            catch (ServiceException exception)
            {
                ModelState.AddModelError(string.Empty, exception.Message);
                model.Errors = GetErrors;
                return Json(model);
            }
        }

        /// <summary>
        /// Show form for editing the specified user.
        /// </summary>
        /// <param name="authorId">
        /// The author Id.
        /// </param>
        [HttpGet]
        public virtual ActionResult Edit(int? authorId)
        {
            var model = new AuthorEditModel();
            if (!authorId.HasValue)
            {
                model.Errors = new List<ErrorModel>
                    {
                        new ErrorModel("Empty value")
                    };
                return BackBoneJson(model);
            }
            var author = _authorsService.GetAuthorById(authorId.Value);

            if (null == author)
            {
                model.Errors = new List<ErrorModel>
                    {
                        new ErrorModel(string.Format("User {0} was not found.", authorId))
                    };
                return BackBoneJson(new AuthorEditModel());
            }

            model = new AuthorEditModel(author);

            return BackBoneJson(model);
        }

        [HttpGet]
        public virtual ActionResult EditTemplate()
        {
            return PartialView(MVC.Admin.Authors.Views.Edit, new AuthorEditModel());
        }

        /// <summary>
        /// Save the specified Author.
        /// </summary>
        /// <param name="authorId">The author id.</param>
        /// <param name="model">The model.</param>
        [HttpPost]
        public virtual ActionResult Edit(int authorId, AuthorEditModel model)
        {
            if (!ModelState.IsValid)
            {
                model.Errors = GetErrors;
                return Json(model);
            }

            var author = (Author)model;
            try
            {
                _authorsService.Save(author);
                model.SuccessMessage = "Author has been successfully updated.";
                return Json(model);
            }
            catch (ServiceException exception)
            {
                ModelState.AddModelError(string.Empty, exception.Message);
                model.Errors = GetErrors;
                return Json(model);
            }
        }

        public virtual ActionResult Validate(int? authorId, string firstName, string lastName, string middleName)
        {
            var idParam = authorId.HasValue ? authorId.Value : 0;
            var result = _authorsService.ValidateAuthor(idParam, firstName, lastName, middleName);
            return Json(result);
        }
    }
}